/*
 * Copyright (c) 2009-2010 VSC co.,Ltd. All rights reserved.
 */
package org.googlecode.viewt.core.tools;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.Writer;

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.googlecode.viewt.core.tools.formbean.FormBeanGenerateCommand;
import org.googlecode.viewt.core.tools.po.POConfigUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class AbstractVelocityGenerator {
//	private Category logger;
	
	private static Logger logger = LoggerFactory
	.getLogger(AbstractVelocityGenerator.class);
	private VelocityEngine ve;
	private VelocityContext context;
	private String copyright;
	private String author;

	public AbstractVelocityGenerator() {
		copyright = "Copyright (c) 2009-2010 Venus Software co.,Ltd. All rights reserved.";
		author = "<a href=\"maito:lizhengle@hotmail.com\">Steven Li</a>";
	}

	public void init() throws Exception {
//		logger = Category.getInstance(getLoggerCategory());
		ve = new VelocityEngine();
		ve.setProperty("runtime.log.logsystem.class",
				"org.apache.velocity.runtime.log.SimpleLog4JLogSystem");
		ve.setProperty("runtime.log.logsystem.log4j.category",
				getLoggerCategory());
		if (getFileTemplatePath() != null) {
			logger.debug(new StringBuffer().append(
					"add file type template path:").append(
					getFileTemplatePath()).toString());
			ve.setProperty("resource.loader", "file");
			ve.setProperty("file.resource.loader.path", getFileTemplatePath());
			logger.debug(new StringBuffer().append(
					"use external file resource path: ").append(
					getFileTemplatePath()).toString());
		}
		ve.addProperty("resource.loader", "classpath");
		ve
				.setProperty("classpath.resource.loader.class",
						"org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
		ve.setProperty("classpath.resource.loader.cache", "false");
		ve.setProperty("classpath.resource.loader.modificationCheckInterval",
				"2");
		ve.setProperty("input.encoding", getInputEncoding());
		ve.setProperty("output.encoding", getOutputEncoding());
		ve.init();
	}

	public boolean assurePath(String path) {
		File writeDir;
		writeDir = new File(path);
		if (writeDir.exists() == false) {
			if (writeDir.mkdirs()) {
				logger.debug(new StringBuffer().append("path: ").append(path)
						.append(" created successful").toString());
				return true;
			}
			logger.error(new StringBuffer().append("Can not create path: ")
					.append(path).toString());
			return false;
		}
		return true;
	}

	public String templateResource(String templateFile) {
		String resource;
		resource = null;
		if (getFileTemplatePath() != null) {
			resource = templateFile;
		} else {
			resource = new StringBuffer().append(getPackageTemplatePath())
					.append("/").append(templateFile).toString();
		}
		return resource;
	}

	public void singleOutput(String templateFile, String outputFileName) throws ResourceNotFoundException, ParseErrorException, Exception {
		String templateResource;
		Template template;
		FileOutputStream fos;
		Writer writer;
		if (assurePath(POConfigUtil.getPathFromFile(outputFileName)) == false) {
			return;
		}
		templateResource = templateResource(templateFile);
		logger.debug(new StringBuffer().append("Begin generate file:").append(
				outputFileName).append(" by template:")
				.append(templateResource).toString());
		
		template = ve.getTemplate(templateResource);
		fos = null;

		fos = new FileOutputStream(outputFileName);

		writer = new BufferedWriter(new java.io.OutputStreamWriter(fos));
		template.merge(context, writer);
		writer.flush();
		writer.close();
		logger.debug(new StringBuffer().append("Generate file:").append(
				outputFileName).append(" end").toString());
	}

	public Logger getLogger() {
		return logger;
	}

	public org.apache.velocity.app.VelocityEngine getEngine() {
		return ve;
	}

	public org.apache.velocity.VelocityContext getContext() {
		return context;
	}

	public void setContext(VelocityContext context) {
		this.context = context;
	}

	public String getCopyright() {
		return copyright;
	}

	public void setCopyright(String copyright) {
		if ((copyright != null) && ("".equals(copyright) == false)) {
			this.copyright = copyright;
		}
	}

	public String getAuthor() {
		return author;
	}

	public void setAuthor(String author) {
		if ((author != null) && ("".equals(author) == false)) {
			this.author = author;
		}
	}

	public String getInputEncoding() {
		return "GBK";
	}

	public String getOutputEncoding() {
		return "GBK";
	}

	abstract public String getLoggerCategory();

	abstract public String getFileTemplatePath();

	abstract public String getPackageTemplatePath();
}
